﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Koala.Pro.Common.Extension
{
    public static class ByteHelper
    {
        public static decimal CalcPercentage(byte value)
        {
            return Math.Round((decimal)(100 * value) / 255m, 2);
        }

        public static int Combine(byte b1, byte b2)
        {
            return (b1 << 8) | b2;
        }

        public static int Combine(byte b1, byte b2, byte b3)
        {
            return (((b1 << 8) | b2) << 8) | b3;
        }

        public static byte GetHigh(this byte data)
        {
            return (byte)(data >> 4);
        }

        public static byte GetLow(this byte data)
        {
            return (byte)(data & 0xFu);
        }

        public static byte GetHigh(this short data)
        {
            return (byte)(data >> 8);
        }

        public static byte GetLow(this short data)
        {
            return (byte)((uint)data & 0xFFu);
        }

        public static byte GetHigh(this int value)
        {
            return (byte)((uint)(value >> 16) & 0xFFFFu);
        }

        public static byte GetLow(this int value)
        {
            return (byte)((uint)value & 0xFFFFu);
        }

        public static byte ParseBinaryString(this string binaryString)
        {
            binaryString = binaryString.Replace(" ", "");
            return Convert.ToByte(binaryString, 2);
        }

        public static byte[] ParseBinaryStringToBytes(this string binaryString)
        {
            binaryString = binaryString.Replace(" ", "");
            int num = binaryString.Length / 8;
            byte[] array = new byte[num];
            for (int i = 0; i < num; i++)
            {
                array[i] = Convert.ToByte(binaryString.Substring(8 * i, 8), 2);
            }
            return array;
        }

        public static byte[] ParseHexString(this string hexString)
        {
            hexString = hexString.Replace(" ", "");
            int length = hexString.Length;
            byte[] array = new byte[length / 2];
            for (int i = 0; i < length; i += 2)
            {
                array[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
            }
            return array;
        }

        public static byte[] ParseHexStringWithDelimiter(this string hexString, string delimiter)
        {
            hexString = hexString.Replace(delimiter, "");
            byte[] array = new byte[hexString.Length / 2];
            for (int i = 0; i < hexString.Length; i += 2)
            {
                array[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
            }
            return array;
        }

        public static byte ParsePercent(this ushort percent)
        {
            double num = Math.Round((double)(int)percent / 100.0 * 255.0, 0);
            return Convert.ToByte($"{(ushort)num:x}".PadLeft(2, '0'), 16);
        }

        public static string ToBinaryString(this byte[] bytes)
        {
            return Convert.ToString(HexHelper.ToUInt(bytes.ToHexString(ToHexadecimal.Loop)), 2);
        }

        public static string ToBinaryString(this byte data)
        {
            return Convert.ToString(data, 2).PadLeft(8, '0');
        }

        public static byte[] ToBytes(this ushort value, bool reverse)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            if (reverse)
            {
                Array.Reverse((Array)bytes);
            }
            return bytes;
        }

        public static byte[] ToBytes(this uint value, bool reverse)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            if (reverse)
            {
                Array.Reverse((Array)bytes);
            }
            return bytes;
        }

        public static byte[] ToBytes(this ulong value, bool reverse)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            if (reverse)
            {
                Array.Reverse((Array)bytes);
            }
            return bytes;
        }

        public static byte[] ToBytes(this ushort value)
        {
            return value.ToBytes(reverse: true);
        }

        public static byte[] ToBytes(this ushort value, int keepArrayLength)
        {
            byte[] array = value.ToBytes(reverse: false);
            if (array.Length < keepArrayLength)
            {
                byte[] array2 = new byte[keepArrayLength];
                array.CopyTo(array2, 0);
                return array2;
            }
            return array;
        }

        public static string ToHexString(this byte data)
        {
            return data.ToString("X2");
        }

        public static string ToHexString(this byte[] bytes, ToHexadecimal type)
        {
            string result = string.Empty;
            switch (type)
            {
                case ToHexadecimal.Loop:
                    result = ToHexStringByLoop(bytes);
                    break;
                case ToHexadecimal.BitConverter:
                    result = ToHexStringByBitConverter(bytes);
                    break;
                case ToHexadecimal.ConvertAll:
                    result = ToHexStringByConvertAll(bytes);
                    break;
            }
            return result;
        }

        public static string ToHexString(this byte[] bytes, int startIndex, int endIndex)
        {
            int num = endIndex - startIndex;
            byte[] array = new byte[num];
            Array.Copy(bytes, startIndex, array, 0, num);
            return ToHexStringByLoop(array);
        }

        public static string ToHexString(this byte[] bytes)
        {
            return ToHexStringByLoop(bytes);
        }

        public static string ToHexStringWithBlank(byte[] bytes)
        {
            return BitConverter.ToString(bytes).Replace("-", " ");
        }

        public static string ToHexStringWithDelimiter(byte[] bytes, string delimiter)
        {
            string text = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    text += bytes[i].ToString("X2");
                    if (i != bytes.Length - 1)
                    {
                        text += delimiter;
                    }
                }
            }
            return text;
        }

        public static int ToInt32(byte[] data)
        {
            return BitConverter.ToInt32(data, 0);
        }

        public static long ToInt64(byte[] data)
        {
            return BitConverter.ToInt64(data, 0);
        }

        public static ushort ToUInt16(byte[] data)
        {
            return BitConverter.ToUInt16(data, 0);
        }

        private static string ToHexStringByBitConverter(byte[] bytes)
        {
            return BitConverter.ToString(bytes).Replace("-", "");
        }

        private static string ToHexStringByConvertAll(byte[] bytes)
        {
            return string.Concat(Array.ConvertAll(bytes, (byte x) => x.ToString("X2")));
        }

        private static string ToHexStringByLoop(byte[] bytes)
        {
            StringBuilder stringBuilder = new StringBuilder(bytes.Length * 2);
            foreach (byte b in bytes)
            {
                stringBuilder.AppendFormat("{0:X2}", b);
            }
            return stringBuilder.ToString();
        }
    }

    public enum ToHexadecimal
    {
        Loop,
        BitConverter,
        ConvertAll
    }
}
